home *** CD-ROM | disk | FTP | other *** search
- ;---------------------------------------------------------------------------
- ; PCMCIA ethernet card driver for A1200
- ;---------------------------------------------------------------------------
- ;
- ; HISTORY:
- ;
- ; 10-4-97 v0.1 - Created by Bruce Abbott (bhabbott@inhb.co.nz)
- ; *** First Aminet Release ***
- ;
- ; 29-4-97 v0.2 - Implemented CMD_ONLINE/OFFLINE/FLUSH (for Miami).
- ;
- ; - Enabled interrupts during RemoteWrite (no more serial
- ; port overruns!).
- ;
- ; 6-5-97 v0.3 - Added a flag so that we won't try to ReleaseCard()
- ; unless there was a successful OwnCard()!
- ;
- ; 17-5-97 v0.4 - CMD_CONFIGINTERFACE now overrides the default hardware
- ; address (for Maimi).
- ;
- ; - Device now goes offline if the PCMCIA card is removed.
- ;
- ; - CMD_ONEVENT implemented.
- ;
- ; - Loosened hardware address verification to accept the
- ; Accton EN2216.
- ;
- ; - Unrolled loops to improve data transfer speed. Now
- ; about 20% faster on an unexpanded A600.
- ;
- ; - Hack to fix problem with missed interrupts. Now we
- ; clear the Gayle interrupt bits instead of letting
- ; card.resource do it for us.
- ;
- ; *** Second Aminet Release ***
- ;
- ; 29-7-97 v0.5 - Accepts 802.3 packets (untested).
- ;
- ; - Sets BROADCAST bit in io_flags when appropriate.
- ;
- ; - Now examines PCMCIA attribute memory to determine
- ; value to write into Card Configuration Register.
- ;
- ; - If attribute memory not found, tries to open the file
- ; "s:cnetdev.config" to get Card Configuration Register
- ; offset, Configuration ID, and ROM Station Address.
- ;
- ; *** Third Aminet Release ***
- ;
- ;
- ; 13-03-1998 PCI version by Krzysztof Rudnik (rudnik@jantar.ias.wat.waw.pl)
-
- include amiga.i ; commodore includes (WB1.3)
- include sanaii.i ; the essential network stuff
- include cnet.i ; hardware specific stuff
-
-
- Printer EQU 0
- VERSION EQU 2
- REVISION EQU 1
-
-
- ; 1uS delay before nic register access
- ; May not be required with slower CPU.
-
- delay MACRO
- tst.b $bfe001 ; at least 1uS, even on fast machines
- ENDM
-
- ;===========================================================================
-
- section device,CODE
-
- start_exe:
- move.l 4,execbase
- move.l #-1,D0 ; it's a device, not an application!
- rts
-
- romtag:
- dc.w RTC_MATCHWORD ; RT_MATCHWORD
- dc.l romtag ; RT_MATCHTAG
- dc.l Endcode ; RT_ENDSKIP
- dc.b RTF_AUTOINIT ; RT_FLAGS
- dc.b VERSION ; RT_VERSION
- dc.b NT_DEVICE ; RT_TYPE
- dc.b 0 ; RT_PRI
- dc.l DeviceName ; RT_NAME
- dc.l IDString ; RT_IDSTRING
- dc.l Init ; RT_INIT
-
- Init:
- dc.l dd_extsize ; data space size
- dc.l funcTable ; pointer to function initializers
- dc.l dataTable ; pointer to data initializers
- dc.l initRoutine ; routine to run at startup
-
- funcTable:
- dc.l Open_Device
- dc.l Close_Device
- dc.l _DevExpunge
- dc.l _Null
- dc.l _DevBeginIO
- dc.l _DevAbortIO
- dc.l -1
-
- dataTable:
- INITBYTE LN_TYPE,NT_DEVICE
- INITLONG LN_NAME,DeviceName
- INITBYTE LIB_FLAGS,LIBF_SUMUSED!LIBF_CHANGED
- INITWORD LIB_VERSION,VERSION
- INITWORD LIB_REVISION,REVISION
- INITLONG LIB_IDSTRING,IDString
- dc.w 0
-
- AppMsg STRINGR "This is not America !!!!"
-
- InitMsg STRINGR "Loading pcinet.device ..."
- NoResourceMsg STRINGR "Unable to open micronik_pci.resource"
- NoLibraryMsg STRINGR "Unable to open pciexpansion.library"
- NoMappingMsg STRINGR "Unable to allocate mapping stru"
- InitMoreMsg STRINGR "More then one network card detected"
- InitNoCardMsg STRINGR "No network card detected"
- InitOKMsg STRINGR "Device initialized successfully"
-
- ;=======================================================
- ; initRoutine
- ;=======================================================
- ;
- ; Called after device has been allocated.
- ; This routine is single threaded
- ;
- ; input: a0 = seglist
- ; d0 = device
- ; a6 = execbase
- ;
- initRoutine:
- movem.l d1-d7/a0-a6,-(A7)
- move.l d0,a5
- move.l a0,dd_seglist(a5) ; seglist for expunge
- move.l a6,execbase ; local copy of execbase
- ; in version 2.0 we can access PCI bus from interrupt routines
- ; we don't need dedicated task
-
- IFGT Printer
-
- bsr DPutMsg
- dc.l InitMsg
-
- ENDC
-
- ; open micronik_pci.resource
- lea.l pcirname(pc),a1
- jsr _LVOOpenResource(a6)
- move.l d0,dd_pcires(a5)
- beq InitFailNoResource
-
- ; zaalokowac pare PCIMapping
- move.l #0,dd_mapping_main(a5)
- move.l #0,dd_mapping_rx(a5)
- move.l #0,dd_mapping_tx(a5)
- move.l #0,dd_mapping_int(a5)
- move.l d0,a6
- jsr PCIRAllocPCIMapping(a6)
- move.l d0,dd_mapping_main(a5)
- beq InitFailNoMapping
- jsr PCIRAllocPCIMapping(a6)
- move.l d0,dd_mapping_rx(a5)
- beq InitFailNoMapping
- jsr PCIRAllocPCIMapping(a6)
- move.l d0,dd_mapping_tx(a5)
- beq InitFailNoMapping
- jsr PCIRAllocPCIMapping(a6)
- move.l d0,dd_mapping_int(a5)
- beq InitFailNoMapping
-
- ; open pciexpansion.library
- move.l execbase(pc),a6
- lea.l pciename(pc),a1
- move.l #0,d0
- jsr _LVOOpenLibrary(a6)
- move.l d0,dd_pcielib(a5)
- tst.l d0
- beq InitFailNoLibrary
-
- ; find NET card
- ; to to chyba lepiej zrobic w open unit - mozna wybrac karte
- move.l #0,a0
- lea.l NET_TAGS(pc),a1
- move.l d0,a6
- jsr PCIEFindPCIDev(a6)
- move.l d0,dd_pciconfig(a5)
- beq InitFailNoCard
- move.l d0,a0
- lea.l NET_TAGS(pc),a1
- jsr PCIEFindPCIDev(a6)
- tst.l d0
- bne InitFailMoreCards
-
- ; wpisac adresy bazowe do PCI mapping
- move.l dd_pciconfig(a5),a0
- move.l pcie_Cfg+pci_BaseAddress0(a0),d0
- btst.l #0,d0
- beq InitMemorySpace
- InitIOSpace:
- and.l #$FFFFFFFC,d0 ; wykasowac 2 najmlodsze bity
- move.b SPACE_IO,d1
- bra InitSpace
- InitMemorySpace:
- and.l #$FFFFFFF0,d0 ; wykasowac 4 najmlodsze bity
- move.b SPACE_MEMORY,d1
- InitSpace:
-
- move.l dd_mapping_main(a5),a1
- move.l d0,pci_Address(a1)
- move.b d1,pci_space(a1)
- move.b pcie_Size0(a0),pci_sizebits(a1)
- move.b #0,pci_flags(a1)
-
- move.l dd_mapping_rx(a5),a1
- move.l d0,pci_Address(a1)
- move.b d1,pci_space(a1)
- move.b pcie_Size0(a0),pci_sizebits(a1)
- move.b #0,pci_flags(a1)
-
- move.l dd_mapping_tx(a5),a1
- move.l d0,pci_Address(a1)
- move.b d1,pci_space(a1)
- move.b pcie_Size0(a0),pci_sizebits(a1)
- move.b #0,pci_flags(a1)
-
- move.l dd_mapping_int(a5),a1
- move.l d0,pci_Address(a1)
- move.b d1,pci_space(a1)
- move.b pcie_Size0(a0),pci_sizebits(a1)
- move.b #0,pci_flags(a1)
-
- IFGT Printer
-
- bsr DPutMsg
- dc.l InitOKMsg
-
- ENDC
-
- move.l a5,d0
- movem.l (A7)+,d1-d7/a0-a6
- rts
-
-
- InitFailMoreCards:
- bsr DPutMsg
- dc.l InitMoreMsg
- bra InitFailCardNumber
-
- InitFailNoCard:
-
- bsr DPutMsg
- dc.l InitNoCardMsg
-
- InitFailCardNumber:
- move.l dd_pcielib(a5),a1
- move.l execbase(pc),a6
- jsr _LVOCloseLibrary(a6)
-
- InitFailNoLibrary:
- bsr DPutMsg
- dc.l NoLibraryMsg
-
- InitFailNoMapping:
- bsr DPutMsg
- dc.l NoMappingMsg
-
- move.l dd_pcires(a5),a6
- move.l dd_mapping_main(a5),a1
- tst.l a1
- beq .IF.map1
- jsr PCIRFreePCIMapping(a6)
- .IF.map1:
- move.l dd_mapping_rx(a5),a1
- tst.l a1
- beq .IF.map2
- jsr PCIRFreePCIMapping(a6)
- .IF.map2:
- move.l dd_mapping_tx(a5),a1
- tst.l a1
- beq .IF.map3
- jsr PCIRFreePCIMapping(a6)
- .IF.map3:
- move.l dd_mapping_int(a5),a1
- tst.l a1
- beq .IF.map4
- jsr PCIRFreePCIMapping(a6)
- .IF.map4:
-
- InitFailNoResource:
- bsr DPutMsg
- dc.l NoResourceMsg
-
-
- InitExpunge:
- move.l #0,d0
- movem.l (A7)+,d1-d7/a0-a6
- rts
-
-
- _Null:
- move.l #0,d0
- rts
-
-
-
- OpenMsg STRINGR "Open pcinet.device"
- DevOpenMsg STRINGR "Device opened successfully"
- ;=================================================================
- ; Open Device
- ;=================================================================
- ;
- ; error = Open_Device(device, ioreq, unitnum, flags)
- ; d0 a6 a1 d0 d1
- ;
- Open_Device:
- movem.l D2-D7/A2-A6,-(A7)
- move.l A6,A5 ; a5 = device
- move.l A1,A4 ; a4 = ioreq
- move.l D0,D4 ; d4 = unit
-
- addq.w #1,LIB_OPENCNT(a5) ; expunge protection
-
- IFGT Printer
-
- bsr DPutMsg
- dc.l OpenMsg
-
- ENDC
-
- move.l a5,a1
- bsr init_device ; init device data structures
- ; can be executed without PCI page
-
- move.l a5,a0
- move.l a4,a1
- move.l d4,d0
- bsr Open_Unit ; open unit
-
- move.l d0,IO_UNIT(a4)
- beq.s .OD.error
-
- move.l A5,A1
- bsr init_card ; init PCMCIA card
-
- tst.l D0
- bne.s .OD.error
-
-
- move.l a5,a1
- bsr init_nic ; init Network Interface Controller
-
- **************************************************************
- * There is no sense to check now - we've checked during
- * device initialization
- * PCI cards are not removable - no insert/remove interrupts
- **************************************************************
- .OD.error:
- .OD.ok:
- bset #DDB_ONLINE,dd_flags(a5) ; ready to accept packets
- moveq #0,d0
- move.b d0,IO_ERROR(a4) ; complete the ioreq
- move.b #NT_REPLYMSG,LN_TYPE(a4)
- addq.w #1,LIB_OPENCNT(a5) ; opened successfully
- .OD.done:
-
- IFGT Printer
-
- bsr DPutMsg
- dc.l EtherAddrMsg
- move.l dd_stationaddress+0(a5),d0
- bsr DPutHexL
- move.w dd_stationaddress+4(a5),d0
- bsr DPutHexW
- bsr DPutMsg
- dc.l EOLMsg
-
- bsr DPutMsg
- dc.l DevOpenMsg
-
- ENDC
-
- subq.w #1,LIB_OPENCNT(a5) ; expunge protection
- move.l #0,d0
- movem.l (A7)+,D2-D7/A2-A6
- rts
-
- EtherAddrMsg STRING "ETHERNET address: "
-
- OpenUnitMsg STRINGR "Open Unit no 0 "
- NoTagsMsg STRINGR "Wrong number of tags"
-
- ;===============================================================
- ; unit=Open Unit(device, ioreq, unitnum)
- ; d0 a0 a1 d0
- ;===============================================================
- ;
- ; Get the caller's buffer copy callback vectors
- ;
- ; NOTE: we only keep the vectors from the current caller
- ;
- ; do not access card - not need to have PCI page
- Open_Unit:
- movem.l D2-D4/A2-A6,-(A7)
- move.l A0,A4 ; A4 = device
- move.l A1,A5 ; A5 = ioreq
- tst.l D0 ; only unit 0 is supported
- bne .OU.error
-
- IFGT Printer
-
- bsr DPutMsg
- dc.l OpenUnitMsg
-
- ENDC
-
- move.l ios2_buffermanagement(A5),D0 ; tag list supplied?
- beq .OU.ok
- moveq #0,D2 ; d2 = number of required tags found
- move.l D0,A0 ; a0 = tag list
- .OU.next_tag:
- move.l (A0)+,D0 ; d0 = tag number
- beq .OU.got_tags ; end of tag list?
- move.l (A0)+,D1 ; d1 = tag value
- cmp.l #S2_COPYFROMBUFF,D0
- beq.s .OU.from ; tag_copyfrombuf ?
- cmp.l #S2_COPYTOBUFF,D0
- bne.s .OU.next_tag ; tag_copytobuf ?
- .OU.to:
- move.l D1,dd_copytobuf(a4) ; store function
- addq.w #1,D2 ; got the tag
- bra .OU.next_tag
- .OU.from:
- move.l D1,dd_copyfrombuf(a4) ; store function
- addq.w #1,D2 ; got the tag
- bra .OU.next_tag
- .OU.got_tags:
- subq.w #2,D2 ; got both tags ?
- beq.s .OU.ok
- .OU.error:
- bsr DPutMsg
- dc.l NoTagsMsg
-
- moveq #0,d0 ; return error
- bra.s .OU.done
- .OU.ok:
- moveq #1,d0 ; return OK
- .OU.done:
- movem.l (A7)+,D2-D4/A2-A6
- rts
-
- ExpungeDevMsg: STRINGR "Expunge pcinet.device"
-
-
- ;============================================================
- ; Expunge Device
- ;============================================================
- ;
- ; called when system wants us to close down
- ;
- _DevExpunge:
- movem.l d1-d4/a0-a6,-(sp)
- move.l a6,a5
-
- IFGT Printer
-
- bsr DPutMsg
- dc.l ExpungeDevMsg
-
- ENDC
-
- tst.w LIB_OPENCNT(a5)
- beq .DE.DOExpunge
-
- bset #LIBB_DELEXP,LIB_FLAGS(a5)
- clr.l d0
- bra .DE.exit
- .DE.DOExpunge
- move.l dd_seglist(a5),d2
-
- ; dealloc PCIMapping structs
- move.l dd_pcires(a5),a6
- move.l dd_mapping_main(a5),a1
- tst.l a1
- beq .DE.map1
- jsr PCIRFreePCIMapping(a6)
- .DE.map1:
- move.l dd_mapping_rx(a5),a1
- tst.l a1
- beq .DE.map2
- jsr PCIRFreePCIMapping(a6)
- .DE.map2:
- move.l dd_mapping_tx(a5),a1
- tst.l a1
- beq .DE.map3
- jsr PCIRFreePCIMapping(a6)
- .DE.map3:
- move.l dd_mapping_int(a5),a1
- tst.l a1
- beq .DE.map4
- jsr PCIRFreePCIMapping(a6)
- .DE.map4:
-
- ; now device typical code
- move.l a5,a1
- move.l execbase(pc),a6
- jsr _LVORemove(a6)
-
- ; free mem for device base
- move.l a5,a1
- clr.l d0
- move.w LIB_NEGSIZE(a5),d0
- suba.l d0,a1
- add.w LIB_POSSIZE(a5),d0
- jsr _LVOFreeMem(a6)
- move.l d2,d0
- ; resource not require to close it
-
- .DE.exit:
- movem.l (sp)+,d1-d4/a0-a6
- rts
-
-
- CloseDeviceMsg: STRINGR "Close pcinet.device"
-
- ;============================================================
- ; Close Device
- ;============================================================
- ;
- ; Seglist = CloseDevice(device, iob)
- ; d0 a6 A1
- ;
- Close_Device:
- movem.l a5/a6,-(sp)
- move.l a6,a5
-
- IFGT Printer
-
- bsr DPutMsg
- dc.l CloseDeviceMsg
-
- ENDC
-
- move.l #-1,d0
- move.l d0,IO_UNIT(a1)
- move.l d0,IO_DEVICE(a1)
-
- move.w LIB_OPENCNT(a5),d0
- beq.s .CD.done ; already closed ?
- subq.w #1,d0
- move.w d0,LIB_OPENCNT(a5)
-
- ; disable interrupt
- move.l dd_mapping_main(a5),a1
- move.l dd_pcires(a5),a6
- jsr PCIRObtainPCIPage(a6)
- move.l map_address(a1),a0
- move.b #0,nic_imr(a0)
- move.b #$FF,nic_isr(a0)
- jsr PCIRReleasePCIPage(a6)
-
- lea dd_netinterrupt(a5),a1 ; init interrupts
- move.l dd_pciconfig(a5),a0
- move.b pcie_Cfg+pci_InterruptLine(a0),d0
- move.l execbase(pc),a6
- jsr _LVORemIntServer(a6)
- tst.w LIB_OPENCNT(a5)
- beq .CD.done
- clr.l d0
- movem.l (sp)+,a5/a6
- rts
-
- .CD.done:
-
- ; check DELexpunge flag
-
- btst #LIBB_DELEXP,LIB_FLAGS(a5)
- beq .CD.Close
-
- bsr _DevExpunge
-
- .CD.Close
- move.l dd_seglist(a5),d0
- movem.l (sp)+,a5/a6
- rts
-
- DevBegIOMsg: STRING "DevBeginIO Start unrecognized command: "
-
-
- ;===============================================================
- ; Dev_BeginIO(iob : a1, devptr : a6)
- ;===============================================================
- ; the entry point for all device commands
- ;
- _DevBeginIO:
- move.w IO_COMMAND(a1),d0
-
- move.b #NT_MESSAGE,LN_TYPE(A1) ; make sure type is message
- moveq #0,d0
- move.w IO_COMMAND(A1),D0 ; get command number
- cmp.w #S2_END,D0
- bhs.s .DB.error ; valid command?
- lsl.w #2,D0
- move.l cmds(PC,D0.w),D0 ; get command vector
- bne.s .DB.ok
- .DB.error:
-
- IFGT Printer
-
- bsr DPutMsg
- dc.l DevBegIOMsg
- bsr DPutHexW
- bsr DPutMsg
- dc.l EOLMsg
-
- ENDC
-
- move.b #IOERR_NOCMD,IO_ERROR(A1)
- bra TermIO ; return invalid command
- .DB.ok:
- clr.b IO_ERROR(A1) ; no errors yet
-
- ; most of the command dont access nic registers
- ; so there is no sense to setup PCI page now
-
- move.l D0,A0
- jmp (A0) ; jump to command
-
-
- ; command vector array ( those marked '*' are commonly used by AmiTCP )
-
- cmds:
- dc.l 0 ; 0
- dc.l 0 ; 1
- dc.l devcmd_read ; 2 = cmd_read *
- dc.l devcmd_write ; 3 = cmd_write *
- dc.l 0 ; 4
- dc.l 0 ; 5
- dc.l 0 ; 6
- dc.l 0 ; 7
- dc.l devcmd_flush ; 8 = cmd_flush
- dc.l devcmd_devicequery ; 9 = S2_DEVICEQUERY *
- dc.l devcmd_getstationaddress ; 10= S2_GETSTATIONADDRESS *
- dc.l devcmd_configinterface ; 11= S2_CONFIGINTERFACE *
- dc.l 0 ; 12
- dc.l 0 ; 13
- dc.l 0 ; 14= S2_ADDMULTICASTADDRESS
- dc.l 0 ; 15= S2_DELMULTICASTADDRESS
- dc.l 0 ; 16= S2_MULTICAST
- dc.l devcmd_broadcast ; 17= S2_BROADCAST *
- dc.l devcmd_tracktype ; 18= S2_TRACKTYPE *
- dc.l 0 ; 19= S2_UNTRACKTYPE
- dc.l 0 ; 20= S2_GETTYPESTATS
- dc.l 0 ; 21= S2_GETSPECIALSTATS
- dc.l 0 ; 22= S2_GETGLOBALSTATS
- dc.l devcmd_onevent ; 23= S2_ONEVENT
- dc.l 0 ; 24= S2_READORPHAN
- dc.l devcmd_online ; 25= S2_ONLINE
- dc.l devcmd_offline ; 26= S2_OFFLINE
-
- dc.l 0
-
-
- DevAbortIOMsg: STRINGR "_DevAbortIO Start"
-
- ;====================================================================
- ; Abort_IO
- ;====================================================================
- ;
- ; try to cancel a pending ioreq
- ;
- ; no PCI access
- _DevAbortIO:
- movem.l A2/A6,-(A7)
- move.l A1,A2
-
- IFGT Printer
-
- bsr DPutMsg
- dc.l DevAbortIOMsg
-
- ENDC
-
- moveq #-1,D0 ; assume failure
- cmp.b #NT_MESSAGE,LN_TYPE(A2) ; only cancel queued ioreq's
- bne.s .DA.done
- move.l execbase(PC),A6
- jsr _LVODisable(A6)
- move.l A2,A1
- jsr _LVORemove(A6) ; remove ioreq from list
- move.b #IOERR_ABORTED,IO_ERROR(A2)
- move.l A2,A1
- jsr _LVOReplyMsg(A6) ; reply to originator's message
- jsr _LVOEnable(A6)
- moveq #0,D0 ; aborted OK
- .DA.done:
- movem.l (A7)+,A2/A6
- rts
-
-
-
- ;===========================================================
- ; termio(ioreq)
- ; a1
- ;===========================================================
- ;
- ; return completed ioreq to sender.
- ;
- ; no PCI access
- TermIOMsg STRINGR "Terminate IO proc"
-
- TermIO:
- movem.l A2/A6,-(A7)
- move.l A1,A2
- move.b IO_ERROR(a1),d0 ; completed OK ?
- beq.s .TI.noerr
- moveq #0,d1
- move.w IO_COMMAND(a2),d1
- move.l IO_DEVICE(A2),A0
- moveq #S2EVENT_ERROR,D0
- bsr DoEvent ; create error event
- .TI.noerr:
- move.b #NT_REPLYMSG,LN_TYPE(A2)
- btst #IOB_QUICK,IO_FLAGS(A2)
- bne.s .TI.quick ; does sender need a reply ?
- move.l A2,A1
- move.l execbase(PC),A6
- jsr _LVOReplyMsg(A6) ; not quick, so send reply
- .TI.quick
- .TI.done:
-
- IFGT Printer
-
- bsr DPutMsg
- dc.l TermIOMsg
-
- ENDC
-
- movem.l (A7)+,A2/A6
- rts
-
-
-
-
- ;====================================================
- ; CMD_READ
- ;====================================================
- ;
- ; no PCI access
-
- CMDReadMsg STRINGR "devcmd_read proc"
-
- devcmd_read:
- movem.l A2/A3/A6,-(A7)
- move.l A1,A2 ; A2 = ioreq
-
- IFGT Printer
-
- bsr DPutMsg
- dc.l CMDReadMsg
-
- ENDC
-
- move.l IO_DEVICE(A2),A3
- btst #DDB_CONFIGURED,dd_flags(A3) ; configured ?
- bne.s .dr.configured
- move.b #S2ERR_BAD_STATE,IO_ERROR(A2)
- moveq #S2WERR_NOT_CONFIGURED,D0
- move.l D0,ios2_wireerror(A2) ; error, device is not configured
- bra.s .dr.error
- .dr.configured:
- bclr #IOB_QUICK,IO_FLAGS(A2) ; must be queued
- beq .dr.readnoquick
-
- IFGT Printer
-
- bsr DPutMsg
- dc.l QuickIOMsg
-
- ENDC
-
- .dr.readnoquick
- move.l execbase(PC),A6
- jsr _LVODisable(A6)
- lea dd_readlist(A3),A0
- move.l A2,A1
- jsr _LVOAddTail(A6) ; add ioreq to read queue
- jsr _LVOEnable(A6)
- bra.s .dr.done
- .dr.error:
- move.l A2,A1
- bsr TermIO ; terminate with error
- .dr.done:
- movem.l (A7)+,A2/A3/A6
- rts
-
- QuickIOMsg STRINGR "Unsuported quick IO read requested"
-
- ;======================================================
- ; CMD_WRITE
- ;======================================================
- ;
- ; no PCI access - Couse
- CMDWriteMsg STRINGR "devcmd_write proc"
-
- devcmd_write:
- movem.l A2/A3/A6,-(A7)
- move.l A1,A2 ; A2 = ioreq
-
- IFGT Printer
-
- bsr DPutMsg
- dc.l CMDWriteMsg
-
- ENDC
-
- move.l IO_DEVICE(A2),A3
- btst #DDB_CONFIGURED,dd_flags(A3) ; configured ?
- bne.s .dw.configured
- move.b #S2ERR_BAD_STATE,IO_ERROR(A2)
- moveq #S2WERR_NOT_CONFIGURED,D0
- move.l D0,ios2_wireerror(A2) ; error, not configured
-
- IFGT Printer
-
- bsr DPutMsg
- dc.l NotCFGMsg
-
- ENDC
-
- bra .dw.error
- .dw.configured:
- btst #SANA2IOB_RAW,IO_FLAGS(A2) ; raw packets ?
- beq.s .dw.cooked
- move.l ios2_datalength(A2),D1
- cmp.l #RAWPKT_SIZE,D1
- bls.s .dw.goodlen ; check packet size
- bra.s .dw.toobig
- .dw.cooked:
- move.l ios2_datalength(A2),D1
- cmp.l #ETHERPKT_SIZE,D1
- bls.s .dw.goodlen
- .dw.toobig:
- move.b #S2ERR_MTU_EXCEEDED,IO_ERROR(A2) ; oops! packet too big
- clr.l ios2_wireerror(A2)
-
- bsr DPutMsg
- dc.l ToBigMsg
-
- bra .dw.error
- .dw.goodlen:
- bclr #IOB_QUICK,IO_FLAGS(A2) ; must be queued
- move.l execbase(PC),A6
- jsr _LVODisable(A6)
- lea dd_writelist(A3),A0
- move.l A2,A1
- jsr _LVOAddTail(A6) ; add ioreq to write queue
- jsr _LVOEnable(A6)
- lea dd_txint(A3),A1
- jsr _LVOCause(A6) ; start tx
- bra.s .dw.done
- .dw.error:
- move.l A2,A1
- bsr TermIO ; terminate with error
- .dw.done:
- movem.l (A7)+,A2/A3/A6
- rts
-
- ToBigMsg STRINGR "Package too big"
- NotCFGMsg STRINGR "Interface not configured"
-
- ;==============================================
- ; CMD_FLUSH
- ;==============================================
- ;
- ; no PCI access
- CMDFlushMsg STRINGR "devcmd_flush proc"
-
-
- devcmd_flush:
- movem.l A1/A2/A6,-(A7)
- move.l IO_DEVICE(A1),A2
-
- IFGT Printer
-
- bsr DPutMsg
- dc.l CMDFlushMsg
-
- ENDC
-
- move.l execbase(PC),A6
- jsr _LVODisable(A6)
- bra.s .df.flushreads
- .df.readloop:
- move.l D0,A1
- move.b #IOERR_ABORTED,IO_ERROR(A1)
- jsr _LVOReplyMsg(A6) ; abort all Read requests
- .df.flushreads:
- lea dd_readlist(A2),A0
- jsr _LVORemHead(A6)
- tst.l D0
- bne.s .df.readloop
- bra.s .df.flushwrites
- .df.writeloop:
- move.l D0,A1
- move.b #IOERR_ABORTED,IO_ERROR(A1)
- jsr _LVOReplyMsg(A6) ; abort all Write requests
- .df.flushwrites:
- lea dd_writelist(A2),A0
- jsr _LVORemHead(A6)
- tst.l D0
- bne.s .df.writeloop
- bra.s .df.flushevents
- .df.eventloop:
- move.l D0,A1 ; abort all Event requests
- move.b #IOERR_ABORTED,IO_ERROR(A1)
- jsr _LVOReplyMsg(A6)
- .df.flushevents:
- lea dd_eventlist(A2),A0
- jsr _LVORemHead(A6)
- tst.l D0
- bne.s .df.eventloop
- jsr _LVOEnable(A6)
- movem.l (A7)+,A1/A2/A6
- bra TermIO
-
-
- ;==============================================
- ; CMD_ONLINE
- ;==============================================
- ;
- ; Try to put device online
- ;
- ; do PCI access - main thread - call DoEvent
- CMDOnlineMsg STRINGR "devcmd_online proc"
-
-
- devcmd_online:
- movem.l d0/a0-a3/a6,-(a7)
-
- IFGT Printer
-
- bsr DPutMsg
- dc.l CMDOnlineMsg
-
- ENDC
-
- move.l IO_DEVICE(a1),a2
- btst #DDB_CONFIGURED,dd_flags(a2) ; won't go online unless configured!
- beq.s .do.error
- bset #DDB_ONLINE,dd_flags(a2)
- bne.s .do.done ; already online ?
-
- move.l a1,a3
-
- move.l dd_mapping_main(a2),a1
- move.l dd_pcires(a2),a6
- jsr PCIRObtainPCIPage(a6)
-
- move.l map_address(a1),a0
- move.b dd_rcr(a2),nic_rcr(a0) ; set receiver to normal mode
-
- jsr PCIRReleasePCIPage(a6)
-
- IFGT Printer
-
- bsr DPutHexL
- bsr DPutMsg
- dc.l Rel1Msg
-
- ENDC
-
- move.l a3,a1
-
- moveq #S2EVENT_ONLINE,D0
- bsr DoEvent ; create ONLINE event
- bra.s .do.done
- .do.error:
- move.b #S2ERR_OUTOFSERVICE,IO_ERROR(a1)
- moveq #S2WERR_UNIT_OFFLINE,d0
- move.l d0,ios2_wireerror(a1)
- .do.done:
- movem.l (a7)+,d0/a0-a3/a6
- bra TermIO
-
- Rel1Msg STRINGR " PCI errors - online"
-
-
- ;==============================================
- ; CMD_OFFLINE
- ;==============================================
- ;
- ; take device offline
- ;
- ; do PCI access - main thread - call DoEvent
-
- CMDOfflineMsg STRINGR "devcmd_offline proc"
-
-
- devcmd_offline
- movem.l d0/a0-a3/a6,-(a7)
-
- IFGT Printer
-
- bsr DPutMsg
- dc.l CMDOfflineMsg
-
- ENDC
-
- move.l IO_DEVICE(a1),a2
- bclr #DDB_ONLINE,dd_flags(a2)
- beq.s .dof.done ; already offline ?
-
- move.l a1,a3
-
- move.l dd_mapping_main(a2),a1
- move.l dd_pcires(a2),a6
- jsr PCIRObtainPCIPage(a6)
-
- move.l map_address(a1),a0
- move.b #DSRC_MON,nic_rcr(a0) ; set receiver to monitor mode
-
- jsr PCIRReleasePCIPage(a6)
-
- IFGT Printer
-
- bsr DPutHexL
- bsr DPutMsg
- dc.l Rel2Msg
-
- ENDC
-
- move.l a3,a1
-
- moveq #S2EVENT_OFFLINE,D0
- bsr DoEvent ; create OFFLINE event
- .dof.done:
- movem.l (a7)+,d0/a0-a3/a6
- bra TermIO
-
- Rel2Msg STRINGR " PCI errors - offline"
-
- ;==============================================
- ; CMD_ONEVENT
- ;==============================================
- ;
- ; queue up event requests
- ;
- ; no PCI access
- CMDOneventMsg STRINGR "devcmd_onevent proc"
-
-
- devcmd_onevent:
- movem.l a1/a6,-(a7)
-
- IFGT Printer
-
- bsr DPutMsg
- dc.l CMDOneventMsg
-
- ENDC
-
- move.l IO_DEVICE(a1),a0
- bclr #IOB_QUICK,IO_FLAGS(a1) ; must be queued
- move.l execbase(PC),A6
- jsr _LVODisable(A6)
- lea dd_eventlist(A0),A0
- jsr _LVOAddTail(A6) ; add ioreq to event queue
- jsr _LVOEnable(A6)
- movem.l (a7)+,a1/a6
- bra TermIO
-
-
-
-
- ;==============================================
- ; CMD_DEVICEQUERY
- ;==============================================
- ;
- ; no PCI access
-
- CMDDeviceQueryMsg STRINGR "devcmd_devicequery proc"
-
- devcmd_devicequery:
- move.l A1,-(A7)
-
- IFGT Printer
-
- bsr DPutMsg
- dc.l CMDDeviceQueryMsg
-
- ENDC
-
- move.l ios2_statdata(A1),A0 ; a0 = caller's buffer
- move.l (A0),D1 ; D1 = buffer size
- move.l size_supplied(pc),D0
- cmp.l D0,D1 ; enough space to store info?
- bhs.s .dq.get
- clr.l S2DQ_SIZESUPPLIED(A0) ; nope!
- bra.s .dq.done
- .dq.get:
- lea S2DQ_SIZESUPPLIED(A0),A1
- lea size_supplied(pc),A0
- subq.l #4,D0 ; skip bytes_available
- bra.s .dq.copy
- .dq.copyloop:
- move.b (A0)+,(A1)+ ; copy info to caller's buffer
- .dq.copy:
- dbf D0,.dq.copyloop
- .dq.done:
- move.l (A7)+,A1
- bra TermIO
-
-
-
- ;==============================================
- ; CMD_GETSTATIONADDRESS
- ;==============================================
- ;
- ; no PCI access
- CMDGetstataddrMsg STRINGR "devcmd_getstationaddress proc"
-
-
- devcmd_getstationaddress:
- move.l A1,-(A7)
-
- IFGT Printer
-
- bsr DPutMsg
- dc.l CMDGetstataddrMsg
-
- ENDC
-
- move.l IO_DEVICE(A1),A0
- lea dd_stationaddress(A0),A0
- move.l A0,D1
- lea ios2_srcaddr(A1),A1
- move.w #ETHER_ADDR_SIZE-1,D0
- .dga.copysrc:
- move.b (A0)+,(A1)+ ; source address = station address
- dbf d0,.dga.copysrc
- move.l (A7),A1
- lea ios2_dstaddr(A1),A1
- move.w #ETHER_ADDR_SIZE-1,D0
- move.l D1,A0
- .dga.copydst:
- moveq #0,d1
- move.b (A0)+,d1
- move.b d1,(A1)+ ; dest address = station address
- dbf d0,.dga.copydst
- move.l (A7)+,A1
- bra TermIO
-
-
- ;==============================================
- ; CMD_CONFIGINTERFACE
- ;==============================================
- ;
- ; NOTE: a default station address has already
- ; been set by init_nic
- ;
- ; do PCI access - main thread - disable
-
- CMDConfigMsg STRINGR "devcmd_configinterface proc"
-
- devcmd_configinterface:
- movem.l d0/a0-a3/a6,-(sp)
-
- IFGT Printer
-
- bsr DPutMsg
- dc.l CMDConfigMsg
-
- ENDC
-
- move.l IO_DEVICE(A1),A2
- move.l ios2_srcaddr(a1),d0
- ble .dci.done ; check for valid address
- move.l d0,dd_stationaddress(a2)
- move.w ios2_srcaddr+4(a1),dd_stationaddress+4(a2)
- move.l execbase(pc),a6
- jsr _LVODisable(a6)
-
- move.l a1,a3
-
- move.l dd_mapping_main(a2),a1
- move.l dd_pcires(a2),a6
- jsr PCIRStorePCIPage(a6)
- move.l map_address(a1),a0
-
- move.b nic_cr(a0),d1 ; remember current command
- delay
- move.b #DSCM_NODMA|DSCM_PG1,nic_cr(a0) ; select bank 1
- delay
- move.b dd_stationaddress+0(a2),nic_par0(a0)
- delay
- move.b dd_stationaddress+1(a2),nic_par1(a0)
- delay
- move.b dd_stationaddress+2(a2),nic_par2(a0)
- delay ; set station address
- move.b dd_stationaddress+3(a2),nic_par3(a0)
- delay
- move.b dd_stationaddress+4(a2),nic_par4(a0)
- delay
- move.b dd_stationaddress+5(a2),nic_par5(a0)
- delay
- move.b d1,nic_cr(a0) ; restore command
-
- jsr PCIRRestorePCIPage(a6)
-
- IFGT Printer
-
- bsr DPutHexL
- bsr DPutMsg
- dc.l Rel3Msg
-
- ENDC
-
- move.l a3,a1
-
- move.l execbase(pc),a6
- jsr _LVOEnable(a6)
-
- bset #DDB_CONFIGURED,dd_flags(a2) ; now configured
- .dci.done:
- movem.l (sp)+,d0/a0-a3/a6
- bra TermIO
-
- Rel3Msg STRINGR " PCI errors - config interface"
-
- ;==============================================
- ; CMD_BROADCAST
- ;==============================================
- ;
- ; no PCI access
- CMDbroadcastMsg STRINGR "devcmd_broadcast proc"
-
-
- devcmd_broadcast:
-
- IFGT Printer
-
- bsr DPutMsg
- dc.l CMDbroadcastMsg
-
- ENDC
-
- move.w #ETHER_ADDR_SIZE-1,D0
- moveq #0,d1
- .db.loop:
- move.b #255,ios2_dstaddr(a1,d1.w) ; dest address = BROADCAST
- addq.w #1,d1
- dbf d0,.db.loop
- .db.doit:
- bra devcmd_write
-
-
-
- ;============================================
- ; CMD_TRACKTYPE
- ;============================================
- ;
- ; This function adds a packet type to the
- ; list of those that are being tracked.
- ;
- ; no PCI access
- CMDTrackTypeMsg STRINGR "devcmd_tracktype proc"
-
-
- devcmd_tracktype:
-
- IFGT Printer
-
- bsr DPutMsg
- dc.l CMDTrackTypeMsg
-
- ENDC
-
- bra TermIO ; but we won't actually track anything
-
-
- ;=========================================
- ; doevent(device, event)
- ; a0 d0
- ;=========================================
- ;
- ; called when an 'important' event occurs
- ;
- ; no PCI access
- doeventmsg STRINGR "Do event proc"
-
-
- DoEvent:
- movem.l D2/A2/A6,-(A7)
- move.l D0,D2
-
- IFGT Printer
-
- bsr DPutMsg
- dc.l doeventmsg
-
- ENDC
-
- move.l dd_eventlist(A0),A2 ; get first ioreq
- move.l execbase(PC),A6
- jsr _LVODisable(A6) ; exclusive access to list required
- bra.s .de.start
- .de.loop:
- move.l ios2_wireerror(A2),D0
- and.l D2,D0 ; should this ioreq be completed?
- beq.s .de.next
- move.l D0,ios2_wireerror(A2) ; clear the event
- move.l A2,A1
- jsr _LVORemove(A6) ; remove ioreq from list
- move.l A2,A1
- bsr TermIO ; return ioreq to owner
- .de.next:
- move.l (A2),A2 ; next ioreq
- .de.start:
- tst.l (A2) ; last ioreq ?
- bne.s .de.loop
- .de.done:
- jsr _LVOEnable(A6) ; other tasks now allowed to access list
- movem.l (A7)+,D2/A2/A6
- rts
-
- ;======================
- ; delay approx 1.5mS
- ;======================
- ;
-
-
- delay1500:
- move.l D0,-(A7)
- move.w #1500,D0
- .del.loop:
- tst.b $bfe001 ; wait 1uS
- dbf D0,.del.loop
- move.l (A7)+,D0
- rts
-
-
-
-
-
- ;==================================================================
- ; RemoteRead(buffer, nicbuffer, length, iobase)
- ; a1 d0.w d1.w a4
- ;==================================================================
- ;
- ; Get a copy of data stored in the network card's onboard RAM.
- ;
- ; buffer = Amiga RAM
- ;
- ; nicbuffer = 16 bit address in card memory
- ;
- ; do PCI access - a4 IOBase
-
- RRMsg STRING "RemoteRead: "
-
- RemoteRead:
-
- IFGT Printer
-
- bsr DPutMsg
- dc.l RRMsg
-
-
- movem.l d0/d1,-(sp)
- clr.l d0
- move.w d1,d0
- bsr DPutHexW
- bsr DPutMsg
- dc.l EOLMsg
- movem.l (sp)+,d0/d1
- bsr DPutMem
-
- ENDC
-
- addq.w #1,D1 ; bump up count to even value
- bclr #0,d1
- swap d1
- delay
- move.b nic_cr(a4),d1 ; save old command
- swap d1
- delay
- move.b #DSCM_NODMA|DSCM_START,nic_cr(A4) ; select bank 0
- delay
- move.b D1,nic_rbcr0(A4) ; set count.lo
- ror.w #8,D1
- delay
- move.b D1,nic_rbcr1(A4) ; set count.hi
- delay
- move.b D0,nic_rsar0(A4) ; set address.lo
- ror.w #8,D0
- delay
- move.b D0,nic_rsar1(A4) ; set address.hi
- delay
- move.b #DSCM_RREAD|DSCM_START,nic_cr(A4) ; request Remote Read
- ror.w #8,D1
-
- asr.w #1,d1
-
- ; d1 - licznik slow
- lea nic_data(a4),a0 ; number of 'move.w' opcodes
- bra .RR.dmqdbf
-
- .RR.dmaread:
- move.w (A0),(A1)+ ; read data words from nic
- .RR.dmqdbf:
- dbf.w d1,.RR.dmaread
-
- move.b #DSIS_RDC,nic_isr(A4) ; Remote DMA Complete
- swap d1
- delay
- move.b d1,nic_cr(a4) ; restore old command
- rts
-
-
-
- ;=================================================================
- ; RemoteWrite( buffer, nicbuffer, count, IObase )
- ; a1 d0.w d1.w a4
- ;=================================================================
- ;
- ; Puts data into the network card's onboard RAM
- ;
- ; buffer = Amiga memory
- ;
- ; nicbuffer = 16 bit address in card RAM
- ;
- ;
- ; do PCI access - A4 - IOBase
-
- RWMsg STRING "RemoteWrite: "
-
- RemoteWrite:
-
- IFGT Printer
-
- bsr DPutMsg
- dc.l RWMsg
-
- movem.l d0/d1,-(sp)
- clr.l d0
- move.w d1,d0
- bsr DPutHexW
- bsr DPutMsg
- dc.l EOLMsg
- movem.l (sp)+,d0/d1
- bsr DPutMem
-
- ENDC
-
-
- addq.w #1,D1
- bclr #0,D1 ; bump up count to even value
- swap d1
- delay
- move.b nic_cr(a4),d1 ; save old command
- swap d1
- delay
- move.b #DSIS_RDC,nic_isr(A4) ; remote DMA complete
- delay
- move.b #DSCM_NODMA|DSCM_START,nic_cr(A4) ; select bank 0
- delay
- move.b D0,nic_rsar0(A4) ; set address.lo
- lsr.w #8,D0
- delay
- move.b D0,nic_rsar1(A4) ; set address.hi
- delay
- move.b D1,nic_rbcr0(A4) ; set count.lo
- ror.w #8,D1
- delay
- move.b D1,nic_rbcr1(A4) ; set count.hi
- delay
- move.b #DSCM_START|DSCM_RWRITE,nic_cr(A4) ; request remote write
- ror.w #8,D1
- lea nic_data(a4),a0
-
- asr.w #1,d1
- ; d1 - licznik transmisji slow
- ; it was using rept 800 move.w (a1)+,(a0)
- ; 68020 have cache - loop is more efective
- bra .RW.dmaread.dbf
-
- .RW.dmaread:
- move.w (A1)+,(A0)
- .RW.dmaread.dbf:
- dbf d1,.RW.dmaread
-
- move.w #30000,D0 ; set timeout
- .RW.check:
- delay
- move.b nic_isr(A4),d1 ; wait for remote DMA complete
- and.b #DSIS_RDC,d1
- bne.s .RW.ok
- dbf D0,.RW.check
- moveq #1,D0 ; timed out error
- bsr DPutMsg
- dc.l RWTimeoutMsg
- bra.s .RW.done
- .RW.ok:
- moveq #0,D0 ; OK
- .RW.done:
- delay
- move.b #DSIS_RDC,nic_isr(a4) ; Remote DMA complete
- swap d1
- delay
- move.b d1,nic_cr(a4) ; restore old command
- rts
-
- RWTimeoutMsg STRINGR "Timeout error in RemoteWRITE"
-
- ;=========================================================
- ; reset_nic(IOBase : a4)
- ;=========================================================
- ;
- ; do PCI access - a4 IOBase
- reset_nic:
- delay
- move.b nic_rst(A4),D0 ; start reset pulse
- delay
- move.b D0,nic_rst(A4) ; end reset pulse
- delay
- move.b #DSCM_NODMA|DSCM_STOP,nic_cr(A4) ; stop controller
- bsr delay1500 ; wait 1.5mS
- move.b #$ff,nic_isr(A4) ; clear all nic ints
- rts
-
-
- ;========================================================================
- ; init_nic(device)
- ; a1
- ;========================================================================
- ;
- ; set up the network card for online operation
- ;
- ; Here we also get the hardware station address from the nic's ROM. The
- ; CNet card sometimes doesn't read its ROM correctly, so in this case we
- ; use a fixed address instead.
- ;
- ; do PCI access - disable - calkowicie
-
- InitNicMsg STRINGR "Init NIC"
- WindowAddMsg STRING "PCI window address: "
- EOLMsg STRINGR " "
- ErrorInitPCIMsg STRINGR " PCI state restored after error"
- SuccessInitPCIMsg STRINGR " PCI state restored after success"
- BadETHAddrMsg STRINGR "BAD ETHERNET ADDRESS !!!! - using defaults"
-
- init_nic:
- movem.l D0-D2/A0-A6,-(A7)
- move.l A1,A5 ; a5 = device data
-
- IFGT Printer
-
- bsr DPutMsg
- dc.l InitNicMsg
-
- ENDC
-
- move.l execbase(PC),A6
- jsr _LVODisable(A6) ; ignore ints while setting up
- btst #DDB_NICUP,dd_flags(a5)
- bne .in.ok ; already initialised ?
- move.b #DSDC_WTS|DSDC_FT1|DSDC_BMS,dd_dcr(A5) ; Word Xfer, FIFO, Burst
- move.b #DSRC_AB,dd_rcr(A5) ; accept broadcast packets
- move.b #INTMASK,dd_imr(A5) ; accept useful interrupts
-
- move.l dd_mapping_main(a5),a1
- move.l dd_pcires(a5),a6
- jsr PCIRStorePCIPage(a6)
- move.l map_address(a1),a4
-
- IFGT Printer
-
- bsr DPutMsg
- dc.l WindowAddMsg
-
- move.l a4,d0
- bsr DPutHexL
- bsr DPutMsg
- dc.l EOLMsg
-
- ENDC
-
- bsr reset_nic ; reset the controller
- delay
- move.b nic_cr(A4),D0 ; get command
- cmp.b #DSCM_NODMA|DSCM_STOP,d0
- bne .in.error ; is it correct ?
- delay
- move.b dd_dcr(A5),nic_dcr(A4) ; set data configuration register
- delay
- move.b #0,nic_rbcr0(A4) ; clear remote byte count
- delay
- move.b #0,nic_rbcr1(A4) ; ''
- delay
- move.b #DSRC_MON,nic_rcr(A4) ; set rx to monitor mode
- delay
- move.b #DSTC_LB0,nic_tcr(A4) ; set tx to loopback mode 1
- delay
- move.b #(RBUFEND/256)-1,nic_bnry(A4) ; set boundary page
- delay
- move.b #RBUF/256,nic_pstart(A4) ; set start of rx ring buffer
- delay
- move.b #RBUFEND/256,nic_pstop(A4) ; set end of rx ring buffer
- delay
- move.b #$ff,nic_isr(a4) ; clear all interrupts
- delay
- move.b #0,nic_imr(a4) ; no interrupts allowed
- delay
- move.b nic_rsr(a4),d0
- delay
- move.b nic_ncr(a4),d0
- delay
- move.b nic_cntr0(a4),d0 ; read status registers
- delay
- move.b nic_cntr1(a4),d0
- delay
- move.b nic_cntr2(a4),d0
- delay
- move.b #ETHER_ADDR_SIZE*2,nic_rbcr0(A4) ; byte count low = (words)
- delay
- move.b #0,nic_rbcr1(A4) ; byte count high = 0
- delay
- move.b #0,nic_rsar0(A4) ; remote start addr low = 0 (ROM)
- delay
- move.b #0,nic_rsar1(A4) ; remote start addr high = 0 (ROM)
- delay
- move.b #DSCM_RREAD,nic_cr(A4) ; start remote read to get
- delay ; station address from ROM
- lea dd_romstationaddress(a5),A0
- move.w #ETHER_ADDR_SIZE-1,D0
- .in.getaddr:
- move.b nic_data(A4),(A0)+ ; get ROM station address
- dbf D0,.in.getaddr ; NOTE: 'move.b' as ROM is 8 bit
- move.w #30000,d1
- .in.waitloop:
- delay
- move.b nic_isr(A4),d0
- and.b #DSIS_RDC,d0 ; wait for remote DMA complete
- dbne d1,.in.waitloop
- tst.w d0
- beq .in.error ; error if timed out
- delay
- move.b #DSIS_RDC,nic_isr(A4) ; clear remote DMA complete int
- lea dd_romstationaddress(a5),a0
- btst #7,(a0)
- bne.s .in.badaddr ; good station address ?
- move.l 2(a0),d0
- beq.s .in.badaddr
- cmp.l #-1,d0
- bne.s .in.gotstation
- .in.badaddr:
- bsr DPutMsg
- dc.l BadETHAddrMsg
-
- lea default_address(pc),a0 ; use known good station address
- .in.gotstation:
- lea dd_stationaddress(a5),a1
- moveq #ETHER_ADDR_SIZE-1,d0
- .in.copyaddr:
- move.b (a0)+,(a1)+ ; copy address to device data
- dbf d0,.in.copyaddr
- delay
- move.b #DSCM_NODMA|DSCM_PG1|DSCM_STOP,nic_cr(A4) ; select bank 1
- delay
- move.b dd_stationaddress+0(a5),nic_par0(a4)
- delay
- move.b dd_stationaddress+1(a5),nic_par1(a4)
- delay
- move.b dd_stationaddress+2(a5),nic_par2(a4)
- delay ; set station address
- move.b dd_stationaddress+3(a5),nic_par3(a4)
- delay
- move.b dd_stationaddress+4(a5),nic_par4(a4)
- delay
- move.b dd_stationaddress+5(a5),nic_par5(a4)
- delay
- move.b #RBUF/256,nic_curr(A4) ; set current page for rx
- move.b #DSCM_NODMA|DSCM_START,d0
- delay
- move.b d0,nic_cr(A4) ; start controller
- delay
- cmp.b nic_cr(A4),D0
- bne .in.error ; command accepted ?
- delay
- move.b dd_rcr(A5),nic_rcr(A4) ; normal rx mode
- delay
- move.b #0,nic_tcr(A4) ; loopback mode off
- delay
- move.b #TBUF/256,nic_tpsr(a4) ; init tx start page
- delay
- move.b #$ff,nic_isr(A4) ; clear all interrupts
- delay
- move.b dd_imr(A5),nic_imr(A4) ; enable nic interrupts
-
- move.l dd_mapping_main(a5),a1
- move.l dd_pcires(a5),a6
- jsr PCIRRestorePCIPage(a6)
-
- IFGT Printer
-
- bsr DPutHexL
- bsr DPutMsg
- dc.l SuccessInitPCIMsg
-
- ENDC
-
- .in.ok
- bset #DDB_NICUP,dd_flags(a5) ; nic is initialised
- moveq #0,D0
- bra.s .in.done ; return OK
-
- .in.error:
- bsr reset_nic ; reset nic after malfunction
- move.l dd_mapping_main(a5),a1
- move.l dd_pcires(a5),a6
- jsr PCIRRestorePCIPage(a6)
-
- bsr DPutHexL
- bsr DPutMsg
- dc.l ErrorInitPCIMsg
- .in.bad:
-
- moveq #-1,D0 ; return error
- .in.done:
- move.l execbase(pc),a6
- jsr _LVOEnable(A6) ; allow interrupt processing
- movem.l (A7)+,D0-D2/A0-A6
- rts
-
-
- ;========================================================
- ; txintcode(device)
- ; a1
- ;========================================================
- ;
- ; send packets to network card. packets will be put
- ; into the card's onboard 16 bit ram, and then
- ; transmitted to the wire.
- ;
- ; do PCI access - interrupt function
- TXIntMsg STRINGR "service tx interrupt"
- txintcode:
- movem.l D4-D7/A2-A6,-(A7)
- move.l A1,A5 ; a5 = device
- ; a4 = IOBase
-
- IFGT Printer
-
- bsr DPutMsg
- dc.l TXIntMsg
-
- ENDC
-
- ; StorePCIPage
- move.l dd_mapping_tx(a5),a1
- move.l dd_pcires(a5),a6
- jsr PCIRStorePCIPage(a6)
-
- move.l map_address(a1),a4
-
- .ti.next:
- btst #DDB_TX,dd_flags(a5) ; quit if tx in progress (status int
- bne .ti.done ; will restart us when tx complete)
- .ti.getreq:
- lea dd_writelist(A5),A0
- move.l execbase(pc),a6 ; remove top ioreq
- jsr _LVORemHead(A6)
- tst.l D0 ; any ioreqs to process?
- beq .ti.done
- move.l D0,A3 ; A3 = ioreq
- lea txbuffer,A1 ; A1 = our internal packet buffer
- btst #SANA2IOB_RAW,IO_FLAGS(A3) ; raw packets?
- beq.s .ti.notraw
- move.l ios2_datalength(A3),D6 ; raw packet is full length
- bra.s .ti.send
- .ti.notraw:
- lea ios2_dstaddr(A3),A0
- moveq #ETHER_ADDR_SIZE-1,D0
- .ti.copy1:
- move.b (A0)+,(A1)+ ; insert dest stationaddr into packet
- dbra D0,.ti.copy1
- lea dd_stationaddress(A5),A0
- moveq #ETHER_ADDR_SIZE-1,D0
- .ti.copy2:
- move.b (A0)+,(A1)+ ; insert src address into packet
- dbra D0,.ti.copy2
- move.l ios2_packettype(A3),D0 ; insert packettype into packet
- move.w D0,(A1)+
- moveq #ether_data,D6
- add.l ios2_datalength(A3),D6 ; d6 = length of header + data
- .ti.send:
- move.l dd_copyfrombuf(a5),a2
- move.l a1,a0
- move.l ios2_data(A3),A1
- move.l ios2_datalength(A3),D0
- jsr (a2) ; call copyfrombuf
- moveq #ETHER_MIN_LEN,D0
- cmp.l D0,D6
- bge.s .ti.min ; d6 adjusted to legal packet size
- move.l D0,D6
- .ti.min:
- move.l D6,D1
- move.w #TBUF,d0
- lea txbuffer,A1
-
- bsr RemoteWrite ; put packet into nic tx buffer
- tst.l D0
- bne.s .ti.termio
- move.l execbase(PC),A6 ; disable interrupts during tx setup
- jsr _LVODisable(A6)
- bset #DDB_TX,dd_flags(A5) ; set our "buffer full" flag
-
- delay
- move.b D6,nic_tbcr0(A4) ; set tx byte count lo
- ror.w #8,D6
- delay
- move.b D6,nic_tbcr1(A4) ; set tx byte count hi
- delay
- move.b #DSCM_NODMA|DSCM_TRANS|DSCM_START,nic_cr(A4) ; start tx
- move.l execbase(PC),A6
- jsr _LVOEnable(A6) ; enable interrupts
- .ti.termio:
- move.l A3,A1
- bsr TermIO ; finish IOrequest
- bra .ti.next ; process next ioreq
- .ti.done:
-
- move.l dd_mapping_tx(a5),a1
- move.l dd_pcires(a5),a6
- jsr PCIRRestorePCIPage(a6)
-
- IFGT Printer
-
- bsr DPutHexL
- bsr DPutMsg
- dc.l Rel4Msg
-
- ENDC
-
- movem.l (A7)+,D4-D7/A2-A6
- moveq #0,d0
- rts
-
- Rel4Msg STRINGR " PCI erros - tx interrupt"
- RXIntMsg STRINGR "service rx interrupt"
-
- ;============================================================
- ; rxintcode(device)
- ; a1
- ;============================================================
- ;
- ; service rx interrupts
- ;
- ; do PCI access - interrupt function
- rxintcode:
- movem.l D6/D7/A3-A6,-(A7)
- move.l A1,A5 ; a5 = device
- ; a4 = IOBase
-
- IFGT Printer
-
- bsr DPutMsg
- dc.l RXIntMsg
-
- ENDC
-
- move.l dd_mapping_rx(a5),a1
- move.l dd_pcires(a5),a6
- jsr PCIRStorePCIPage(a6)
-
- move.l map_address(a1),a4 ; a4 = nic registers
-
- move.l execbase(PC),A6
- .ri.nextpage:
- jsr _LVODisable(A6)
- delay
- move.b #DSCM_NODMA|DSCM_PG1|DSCM_START,nic_cr(A4) ; select bank 1
- moveq #0,D7
- move.b nic_curr(A4),D7 ; d7 = current page
- delay
- move.b #DSCM_NODMA|DSCM_START,nic_cr(A4) ; select bank 0
- jsr _LVOEnable(A6)
- moveq #0,D6
- delay
- move.b nic_bnry(A4),D6
- addq.w #1,D6 ; d6 = next page (boundary+1)
- cmp.w #RBUFEND/256,D6
- blo.s .ri.nowrap ; end of buffer mem ?
- moveq #RBUF/256,D6 ; wrap around to start
- .ri.nowrap:
- cmp.w D6,D7 ; current page = next page ?
- beq .ri.done ; if so then nothing to get
- move.w D6,D0
- asl.w #8,D0 ; d0 = 16 bit page address
- lea rx_header(pc),A1 ; a1 = buffer
- moveq #20,D1 ; 20 bytes to get
- bsr RemoteRead ; get packet header
- move.b rx_header+prhdr_status(pc),d0
- and.b #DSRS_RPC,d0 ; complete packet received ?
- bne.s .ri.goodpacket
- addq.l #1,dd_errors(a5) ; another packet error
- bra.s .ri.next
- .ri.goodpacket:
- move.w D6,D0
- lea rx_header(pc),A1
- bsr readpacket ; read whole packet into ioreqs
- .ri.next:
- moveq #0,D0
- move.b rx_header+prhdr_nxtpg(pc),D0 ; get next page number
- move.w D0,D7
- subq.w #1,D0 ; nxtpage-1 = new boundary
- cmp.w #RBUF/256,D0
- bge.s .ri.boundary ; wrap if before 1st page
- moveq #(RBUFEND/256)-1,D0
- .ri.boundary:
- delay
- move.b D0,nic_bnry(A4) ; set new boundary
- bra .ri.nextpage ; back for more
- .ri.done:
- delay
- move.b #DSCM_NODMA|DSCM_START,nic_cr(A4) ; select bank 0
- jsr _LVODisable(A6)
- delay
- move.b nic_rsr(a4),d0 ; read rx status
- delay
- move.b nic_cntr0(A4),D0
- delay
- move.b nic_cntr1(A4),D0 ; read counters
- delay
- move.b nic_cntr2(A4),D0
- or.b #DSIM_OVWE|DSIM_RXEE|DSIM_PRXE,dd_imr(A5)
- move.b dd_imr(a5),nic_imr(a4) ; allow rx interrupts
- jsr _LVOEnable(A6)
-
- move.l dd_mapping_rx(a5),a1
- move.l dd_pcires(a5),a6
- jsr PCIRRestorePCIPage(a6)
-
- IFGT Printer
-
- bsr DPutHexL
- bsr DPutMsg
- dc.l Rel5Msg
-
- ENDC
-
- movem.l (A7)+,D6/D7/A3-A6
- moveq #0,D0
- rts
-
- Rel5Msg STRINGR " PCI errors - rx interrupt"
-
-
- ;==============================================================
- ; readpacket( device, pkthdr, page, IOBase)
- ; a5 a1 d0.w A4
- ;==============================================================
- ;
- ; get packet from network card and feed it to next ioreq
- ;
- ; Inputs:
- ;
- ; pkthdr = packet header info extracted from nic
- ;
- ; page = 256 byte page in nic RAM that holds packet
- ;
- ;
- ; call Remote Read - called from interrupt
- ; ZAMIANIC A4 NA A2
-
- ReadPackMsg STRINGR "Read packet function"
-
- readpacket:
- movem.l D3-D7/A2-A6,-(A7)
- move.l D0,D7 ; D7 = page
- move.l A1,A2 ; a2 = header
- moveq #0,D6
-
- IFGT Printer
-
- bsr DPutMsg
- dc.l ReadPackMsg
-
- ENDC
-
- move.b prhdr_sz1(A2),D6
- lsl.w #8,D6 ; D6 = packet data length
- move.b prhdr_sz0(A2),D6
- sub.w #prhdr_sizeof+ether_data,D6 ; D6 = length of user data
- moveq #0,D3
- move.w prhdr_sizeof+ether_type(A2),D3 ; d3 = type
- move.l dd_readlist(A5),A3 ; a3 = first ioreq
- bra.s .rp.getreq ; find a suitable ioreq
- .rp.checkreq:
- cmp.l ios2_packettype(A3),D3 ; does it want our packet ?
- beq.s .rp.gotreq
- cmp.w #1500,d3
- bhi.s .rp.nextreq ; accept 802.3 packets
- cmp.l #1500,ios2_packettype(A3)
- bls.s .rp.gotreq
- .rp.nextreq:
- move.l D1,A3 ; a3 = next ioreq in list
- .rp.getreq:
- move.l (A3),D1 ; end of list ?
- bne.s .rp.checkreq
- bra .rp.done
- .rp.gotreq:
- move.l A3,A1
- move.l execbase(PC),A6
- jsr _LVORemove(A6) ; remove ioreq from list
- lea ios2_dstaddr(A3),A0
- moveq #ETHER_ADDR_SIZE-1,D0
- .rp.dst:
- move.b (A2)+,(A0)+ ; extract the dest address
- dbf D0,.rp.dst
- cmp.w #$ffff,ios2_dstaddr(a3)
- bne.s .rp.getsrc ; address = Broadcast ?
- cmp.l #$ffffffff,ios2_dstaddr+2(a3)
- bne.s .rp.getsrc
- bset #SANA2IOB_BCAST,IO_FLAGS(a3) ; set BROADCAST flag in ioreq
- .rp.getsrc:
- lea ios2_srcaddr(A3),A0
- moveq #ETHER_ADDR_SIZE-1,D0
- .rp.src:
- move.b (A2)+,(A0)+ ; extract the src address
- dbf D0,.rp.src
- move.w D7,D5
- asl.w #8,D5 ; address=page*256
- add.w #prhdr_sizeof+ether_data,D5 ; skip pageheader and etherheader
- btst #SANA2IOB_RAW,IO_FLAGS(A3)
- beq.s .rp.getpacket ; is etherheader wanted ?
- moveq #ether_data,D0
- add.l D0,D6 ; add header length for raw packet
- sub.w D0,D5 ; backup nic address to include header
- .rp.getpacket:
- lea rxbuffer,A1
- move.w D5,D0
- move.w D6,D1
- bsr RemoteRead ; get packet from network card's RAM
- move.l dd_copytobuf(a5),a2
- move.l ios2_data(A3),A0
- lea rxbuffer,A1
- move.l D6,ios2_datalength(A3) ; set data length in ioreq
- move.l d6,d0
- jsr (a2) ; call copytobuf
- move.l A3,A1
- bsr TermIO ; IO finished
- .rp.done:
- movem.l (A7)+,D3-D7/A2-A6
- rts
-
- ;======================================================================
- ; init_card(device)
- ; a1
- ;======================================================================
- ;
- ; Initialise PCMCIA card
- ;
- ; we use PCI card instead of PCMCIA one
- ; no PCI access
-
- InitCardMsg STRINGR "Init card"
-
- init_card:
- movem.l D2-D6/A3/A6,-(A7)
- move.l A1,A3 ; a3 = device
-
- IFGT Printer
-
- bsr DPutMsg
- dc.l InitCardMsg
-
- ENDC
-
- lea dd_netinterrupt(a3),a1 ; init interrupts
- lea DeviceName(pc),a0
- move.l a0,LN_NAME(a1)
- move.b #20,LN_PRI(a1) ; high priority for I/O card
- move.l a3,IS_DATA(a1)
- move.l #status_int_code,IS_CODE(a1)
- move.l dd_pciconfig(a3),a0
- move.b pcie_Cfg+pci_InterruptLine(a0),d0
- move.l execbase(pc),a6
- jsr _LVOAddIntServer(a6)
-
- .ic.ok:
- moveq #0,D0 ; card is active, return OK
- .ic.done:
- movem.l (A7)+,D2-D6/A3/A6
- rts
-
-
-
-
- ;=================================================================
- ; initialise device data structures
- ;=================================================================
- ;
- ; init_device(device)
- ; a1
- ;
- ; there is no need to have PCIpage - no PCI access
- InitDevMsg STRINGR "init_device"
-
- init_device:
- move.l A3,-(A7)
- move.l A1,A3
-
- IFGT Printer
-
- bsr DPutMsg
- dc.l InitDevMsg
-
- ENDC
-
- bset #DDB_DEVINIT,dd_flags(A3) ; already initialised ?
- bne .id.done
- lea dd_readlist(A3),A0
- move.l A0,MLH_TAILPRED(A0)
- lea MLH_TAIL(A0),A1 ; New MinList for read queue
- clr.l (A1)
- move.l A1,(A0)
- lea dd_writelist(A3),A0
- move.l A0,MLH_TAILPRED(A0) ; New MinList for write queue
- lea MLH_TAIL(A0),A1
- clr.l (A1)
- move.l A1,(A0)
- lea dd_eventlist(A3),A0 ; New MinList for event queue
- move.l A0,MLH_TAILPRED(A0)
- lea MLH_TAIL(A0),A1
-
- clr.l (A1)
- move.l A1,(A0)
- move.b #NT_INTERRUPT,dd_rxint+LN_TYPE(a3)
- move.b #16,dd_rxint+LN_PRI(a3)
- lea rxintname(pc),a0
- move.l a0,dd_rxint+LN_NAME(a3) ; set up rx swi
- lea rxintcode(pc),a0
- move.l a0,dd_rxint+IS_CODE(a3)
- move.l a3,dd_rxint+IS_DATA(a3)
- move.b #NT_INTERRUPT,dd_txint+LN_TYPE(a3)
- move.b #0,dd_txint+LN_PRI(a3)
- lea txintname(pc),a0
- move.l a0,dd_txint+LN_NAME(a3) ; set up tx swi
- lea txintcode(pc),a0
- move.l a0,dd_txint+IS_CODE(a3)
- move.l a3,dd_txint+IS_DATA(a3)
- .id.done:
- move.l (A7)+,A3
- rts
-
-
- ; INT from PCI card
- ;
- ; Occurs whenever a PCMCIA status line changes
- ;
- ; eg. when the network card activates it's interrupt line
- ;
- ;
- ; entry: a1 = device
- ;
- ; exit: d0 must be preserved!
- ;
- ; do PCI access - interrupt function
-
- IntMsg STRINGR " => PCI Interrupt"
-
- status_int_code:
- movem.l D2-D6/A0-A6,-(A7)
- move.l A1,A4 ; a4 = device
-
- btst #DDB_ONLINE,dd_flags(a4) ; is device online ?
- beq .si.done
-
- ; StorePCIPage - interrupt server
- move.l dd_mapping_int(a4),a1
- move.l dd_pcires(a4),a6
- jsr PCIRStorePCIPage(a6)
- move.l map_address(a1),a3 ; a3 = nic I/O address
-
- delay
- move.b nic_cr(a3),d5 ; save old command
- delay
- move.b #0,nic_imr(a3) ; prevent nic interrupts
- bra .si.checkint
-
- ; interrupt service loop (D3 = interrupt status)
-
- .si.intloop:
- ; d3 - status wypisac
-
- IFGT Printer
-
- clr.l d0
- move.b d3,d0
- bsr DPutHexB
- bsr DPutMsg
- dc.l IntMsg
-
- ENDC
-
- btst #DSIB_ROVRN,d3
- beq .si.no_overflow
-
- ; receiver ring buffer overflowed (eek!)
- addq.l #1,dd_overflows(a4)
- delay
- move.b #0,nic_rbcr0(a3)
- delay
- move.b #0,nic_rbcr1(a3) ; reset remote byte count
- delay
- move.b #DSTC_LB0,nic_tcr(a3)
- delay ; monitor mode
- move.b #DSRC_MON,nic_rcr(a3)
- delay
- move.b #DSCM_NODMA|DSCM_START,nic_cr(a3) ; try to restart controller
- delay
- move.b #DSRC_AB,nic_rcr(a3)
- delay ; normal rx mode
- move.b #0,nic_tcr(a3)
-
- .si.no_overflow:
- btst #DSIB_RXE,d3
- beq.s .si.norxerr
- addq.l #1,dd_errors(a4)
- delay
- move.b nic_rsr(a3),d0 ; read rx status
- delay
- move.b nic_cntr0(A3),D0
- delay
- move.b nic_cntr1(A3),D0 ; read counters
- delay
- move.b nic_cntr2(A3),D0
- bra.s .si.rx
-
- .si.norxerr:
- btst #DSIB_RX,d3
- beq.s .si.no_rx
-
- ; new packet(s) arrived in receive ring buffer
- .si.rx:
- and.b #~(DSIM_OVWE|DSIM_RXEE|DSIM_PRXE),dd_imr(A4) ; ignore rx ints
- lea dd_rxint(A4),A1
- move.l execbase(PC),A6
- jsr _LVOCause(A6) ; to copy packet(s) into waiting ioreqs
-
- .si.no_rx:
- btst #DSIB_TXE,d3
- bne.s .si.tx
- btst #DSIB_TX,d3
- beq .si.no_tx
-
- ; a packet has just been transmitted
- .si.tx:
- moveq #0,d0
- delay
- move.b nic_ncr(A3),d0 ; read collision count
- add.l d0,dd_collisions(a4)
- bclr #DDB_TX,dd_flags(A4) ; buffer now free
- lea dd_txint(A4),A1
- move.l execbase(PC),A6
- jsr _LVOCause(A6) ; to transmit next packet
-
- .si.no_tx:
- btst #DSIB_CTRS,d3 ; counter overflow ?
- bne.s .si.counter
- bra.s .si.checkint ; all ints processed
-
- ; counter overflow
- .si.counter:
- delay
- move.b nic_cntr0(A3),D0
- delay
- move.b nic_cntr1(A3),D0 ; read counters
- delay
- move.b nic_cntr2(A3),D0
-
- .si.checkint:
- delay
- move.b nic_isr(a3),D3 ; D3 = nic interrupt status
- delay
- move.b d3,nic_isr(a3) ; clear current interrupt bit(s)
- and.b dd_imr(a4),d3
- bne .si.intloop ; any valid interrupts ?
- .si.end:
- delay
- move.b d5,nic_cr(a3) ; restore old command
-
- move.b dd_imr(a4),nic_imr(a3) ; enable nic interrupts
- ; restore pci
- move.l dd_mapping_int(a4),a1
- move.l dd_pcires(a4),a6
- jsr PCIRRestorePCIPage(a6)
-
- .si.done:
- clr.l d0
- movem.l (A7)+,D2-D6/A0-A6
- rts
-
- rxintname:
- dc.b "pcinet rx softint",0
- txintname:
- dc.b "pcinet tx softint",0
-
- pcirname:
- dc.b "micronik_pci.resource",0
-
- pciename:
- dc.b "pciexpansion.library",0
- pciever: EQU 0
-
-
- NET_TAGS: dc.l PCIE_BASECLASSCODE,2 ; network controller
- dc.l 0,0
-
- dosname:
- dc.b "dos.library",0
-
- configname:
- dc.b "S:cnetdev.config",0
-
- DeviceName:
- dc.b "pcinet.device",0
- IDString:
- dc.b "$VER: pcinet.device "
- dc.b VERSION+48,".",REVISION+48," "
- dc.b "02.04.1998"
- dc.b " by Krzysztof Rudnik (rudnik@ias.wat.waw.pl)",10,0
-
- CNOP 0,4
-
- ; devicequery block
-
- size_supplied:
- dc.l S2DQ_SIZE ; bytes supplied (size of this block)
- dc.l 0 ; this is type 0
- dc.l 0 ; this document is level 0
- dc.w ETHER_ADDR_SIZE*8 ; address size in bits
- dc.l ETHERPKT_SIZE ; maximum packet data size
- dc.l 10000000 ; line rate (10 Megabits/sec)
- dc.l S2WIRETYPE_ETHERNET ; what the wire is
-
-
- ; default station address to use if the card won't give it to us.
-
- default_address:
- dc.b $00,$00,$12,$34,$56,$78 ; replace this with your card's address!
-
-
- ;--------------------------------------------------------
- ; Global data
- ;--------------------------------------------------------
-
- execbase dc.l 0 ; local copy of execbase
-
- rx_header:
- ds.b 20 ; received packet header
-
-
- DPutMsg: ; jak DPutStr tylko parametr jest dc.l po wywolaniu
- movem.l d0/a0,-(sp)
- ; poprawic adres powrotu
- addq.l #4,8(sp)
- ; parametr w kodzie po instrukcji wywolania
- move.l 8(sp),a0
- move.l -4(a0),a0
- ; w A0 adres stringu
- bra DPutStr1
-
- DPutStrtt: movem.l d0/a0,-(sp)
- DPutStr1: move.b (a0)+,d0
- bne .Dputchar
- movem.l (sp)+,d0/a0
- rts
- .Dputchar: bsr PRawPutChar
- bra DPutStr1
-
- ; wypisac long d0 w HEXie jako %8X
- DPutHexL: swap d0
- bsr DPutHexW
- swap d0
- ; wypisac word d0 w HEXie jako %4X
- DPutHexW: ror.w #8,d0
- bsr DPutHexB
- rol.w #8,d0
- ; wypisac byte d0 w HEXie jako %2X
- DPutHexB: ror.b #4,d0
- bsr DPutHexD
- rol.b #4,d0
- ; wypisanie najmlodszych 4 bitow d0 w hex
- DPutHexD: movem.l d0/a0,-(sp)
- and.l #$F,d0
- move.b HexDigits(pc,d0.w),d0
- bsr PRawPutChar
- movem.l (sp)+,d0/a0
- rts
-
- HexDigits: dc.b "0123456789ABCDEF"
-
- ; to bylo w debug.lib - ale ja chce to miec razem, zeby nie kombinowac
- ; z linkowaniem
- DPutChar:
- PRawPutChar: tst.b $BFD000
- tst.b $BFD000
- l30$166: btst #1,$BFD000
- bne l30$555
- btst #2,$BFD000
- beq l30$555
- btst #0,$BFD000
- bne.s l30$166
- move.b #$FF,$BFE301
- move.b d0,$BFE101
- tst.b $BFD000
- tst.b $BFD000
- l30$555: rts
-
-
- ; Additional function called from RemoteRead & RemoteWrite
- ; the same parameters - HEX dumps memory address A1, len D1
- ; do not modify any registers. Limits count to 128 bytes
- ;=================================================================
- ; DumpMem( buffer, count)
- ; a1 d1.w
- ;=================================================================
- ;
- DPutMem: movem.l d0-d4/a1,-(sp)
- cmp.w #256,d1
- blt lenok
- move.w #256,d1
- lenok:
- move.l #0,d3 ; BYTE address
- LineLoop: move.l #15,d4
- move.l d3,d0
- bsr DPutHexW
- bsr DPutMsg
- dc.l LineHeaderMsg
-
- ByteLoop: clr.l d0
- move.b (a1)+,d0
- add.l #1,d3
- bsr DPutHexB
- move.b #' ',d0
- bsr DPutChar
- sub.w #1,d1
- dbeq d4,ByteLoop
- LineTrailer:
- bsr DPutMsg
- dc.l EOLMsg
-
- tst.w d1
- bne LineLoop
- bsr DPutMsg
- dc.l DumpTrailerMsg
- movem.l (sp)+,d0-d4/a1
- rts
-
- LineHeaderMsg STRING " : "
- DumpTrailerMsg STRINGR "==================="
-
- Endcode:
-
- section buffers,bss
-
- rxbuffer:
- ds.b 1600 ; received packet buffer
-
- txbuffer:
- ds.b 1600 ; transmit packet buffer
-
- END
-